/**
 * 该文件可自行根据业务逻辑进行调整
 */
import type { RequestClientOptions } from '@vben/request';
import type { AuthApi } from './core/auth';

import { useAppConfig } from '@vben/hooks';
import { preferences } from '@vben/preferences';
import {
  authenticateResponseInterceptor,
  defaultResponseInterceptor,
  errorMessageResponseInterceptor,
  RequestClient,
} from '@vben/request';
import { useAccessStore } from '@vben/stores';

import { message } from 'ant-design-vue';

import { useAuthStore } from '#/store';

import { refreshTokenApi } from './core';

// 修改为Go后端API地址
const apiURL = import.meta.env.VITE_API_URL || 'http://localhost:8080/api/v1';

// 从Cookie中获取CSRF令牌
function getCSRFTokenFromCookie(): string | null {
  const cookies = document.cookie.split(';');
  for (const cookie of cookies) {
    const parts = cookie.trim().split('=');
    if (parts.length === 2) {
      const name = parts[0];
      const value = parts[1];
      if (name === 'csrf_token' && value) {
        console.log('从Cookie中获取到CSRF令牌:', value);
        return decodeURIComponent(value);
      }
    }
  }
  console.log('未在Cookie中找到CSRF令牌');
  return null;
}

// 获取CSRF令牌（如果不存在则发送请求获取）
async function ensureCSRFToken(): Promise<string | null> {
  // 先尝试从Cookie中获取
  let token = getCSRFTokenFromCookie();
  if (token) {
    console.log('从Cookie中获取到CSRF令牌:', token);
    return token;
  }

  console.log('尝试通过请求获取CSRF令牌...');
  // 如果Cookie中没有，发送请求获取
  try {
    const apiURL = import.meta.env.VITE_API_URL || 'http://localhost:8080';
    console.log('请求CSRF令牌的URL:', `${apiURL}/test-csrf`);
    
    const response = await fetch(`${apiURL}/test-csrf`, {
      method: 'GET',
      credentials: 'include',
      headers: {
        'Accept': 'application/json',
        'Content-Type': 'application/json',
      },
    });

    if (response.ok) {
      const result = await response.json();
      console.log('获取CSRF令牌响应:', result);
      
      // 请求成功后，再次从Cookie中获取
      token = getCSRFTokenFromCookie();
      if (token) {
        console.log('成功获取CSRF令牌:', token);
        return token;
      } else if (result.new_token) {
        // 如果响应中包含新令牌，使用它
        console.log('使用响应中的新令牌:', result.new_token);
        return result.new_token;
      }
    } else {
      console.error('获取CSRF令牌失败:', response.status, response.statusText);
      const errorText = await response.text();
      console.error('错误详情:', errorText);
    }
  } catch (error) {
    console.error('获取CSRF令牌出错:', error);
  }

  return null;
}

// 创建请求客户端时确保baseURL正确设置
function createRequestClient(baseURL: string, options?: RequestClientOptions) {
  const client = new RequestClient({
    baseURL: baseURL.endsWith('/') ? baseURL : `${baseURL}/`,
    timeout: 60000,
    withCredentials: true,
    ...options,
  });

  /**
   * 重新认证逻辑
   */
  async function doReAuthenticate() {
    console.warn('Access token or refresh token is invalid or expired. ');
    const accessStore = useAccessStore();
    const authStore = useAuthStore();
    accessStore.setAccessToken(null);
    if (
      preferences.app.loginExpiredMode === 'modal' &&
      accessStore.isAccessChecked
    ) {
      accessStore.setLoginExpired(true);
    } else {
      await authStore.logout();
    }
  }

  /**
   * 刷新token逻辑
   */
  async function doRefreshToken() {
    const accessStore = useAccessStore();
    const resp = await refreshTokenApi();
    const newToken = resp.accessToken;
    accessStore.setAccessToken(newToken);
    return newToken;
  }

  function formatToken(token: null | string) {
    return token ? `Bearer ${token}` : null;
  }

  // 请求头处理
  client.addRequestInterceptor({
    fulfilled: async (config) => {
      try {
        const accessStore = useAccessStore();

        // 添加认证令牌
        config.headers.Authorization = formatToken(accessStore.accessToken);
        
        // 添加CSRF令牌（如果存在）
        const csrfToken = await ensureCSRFToken();
        if (csrfToken) {
          config.headers['X-CSRF-Token'] = csrfToken;
        }
        
        // 添加语言设置
        config.headers['Accept-Language'] = preferences.app.locale;
        
        // 添加Origin头
        config.headers['Origin'] = window.location.origin;
        
        return config;
      } catch (error) {
        console.error('请求拦截器错误:', error);
        return config;
      }
    },
    rejected: (error) => {
      console.error('请求被拒绝:', error);
      return Promise.reject(error);
    },
  });

  // 处理返回的响应数据格式
  client.addResponseInterceptor(
    defaultResponseInterceptor({
      codeField: 'code',
      dataField: 'data',
      successCode: 200, // 修改为Go后端的成功状态码
    }),
  );

  // token过期的处理
  client.addResponseInterceptor(
    authenticateResponseInterceptor({
      client,
      doReAuthenticate,
      doRefreshToken,
      enableRefreshToken: preferences.app.enableRefreshToken,
      formatToken,
    }),
  );

  // 通用的错误处理,如果没有进入上面的错误处理逻辑，就会进入这里
  client.addResponseInterceptor(
    errorMessageResponseInterceptor((msg: string, error) => {
      // 获取后端返回的错误信息
      const responseData = error?.response?.data ?? {};
      let errorMessage = '';
      
      // 处理Go后端的错误响应格式
      if (responseData.message) {
        errorMessage = responseData.message;
      } else if (responseData.error) {
        errorMessage = responseData.error;
      } else if (typeof responseData === 'string') {
        errorMessage = responseData;
      }
      
      // 根据状态码处理特定错误
      const statusCode = error?.response?.status;
      switch (statusCode) {
        case 400:
          message.error(errorMessage || '请求参数错误');
          break;
        case 401:
          // 未授权，已在认证拦截器中处理
          console.warn('未授权访问:', errorMessage);
          break;
        case 403:
          // 如果是CSRF错误，尝试刷新页面获取新的CSRF令牌
          if (errorMessage.includes('CSRF')) {
            message.error('安全验证失败，请刷新页面后重试');
            // 可以选择自动刷新页面
            // setTimeout(() => window.location.reload(), 2000);
          } else {
            message.error(errorMessage || '无权访问该资源');
          }
          break;
        case 404:
          message.error(errorMessage || '请求的资源不存在');
          break;
        case 429:
          message.error(errorMessage || '请求过于频繁，请稍后再试');
          break;
        default:
          if (statusCode && statusCode >= 500) {
            message.error(errorMessage || '服务器内部错误，请稍后再试');
          } else {
            message.error(errorMessage || msg || '请求失败');
          }
      }
    }),
  );

  return client;
}

export const requestClient = createRequestClient(apiURL, {
  responseReturn: 'data',
});

// 测试CSRF保护
async function testCSRF(): Promise<boolean> {
  try {
    const apiURL = import.meta.env.VITE_API_URL || 'http://localhost:8080';
    
    // 首先发送GET请求获取最新的CSRF令牌
    console.log('发送GET请求获取最新的CSRF令牌...');
    const getResponse = await fetch(`${apiURL}/test-csrf`, {
      method: 'GET',
      credentials: 'include',
      headers: {
        'Accept': 'application/json',
        'Content-Type': 'application/json',
      },
    });
    
    const getResult = await getResponse.json();
    console.log('GET测试结果:', getResult);
    
    // 确保在发送POST请求前获取最新的CSRF令牌
    await new Promise(resolve => setTimeout(resolve, 100)); // 短暂延迟确保Cookie已更新
    
    // 重新获取最新的CSRF令牌
    const csrfToken = getCSRFTokenFromCookie();
    console.log('测试CSRF - 当前令牌:', csrfToken);
    
    if (!csrfToken) {
      console.error('未能获取CSRF令牌，无法进行测试');
      return false;
    }
    
    // 准备请求头
    const headers: Record<string, string> = {
      'Content-Type': 'application/json',
      'X-CSRF-Token': csrfToken
    };
    
    // 发送POST请求测试
    console.log('发送POST请求测试CSRF...');
    console.log('使用的CSRF令牌:', csrfToken);
    const postResponse = await fetch(`${apiURL}/test-csrf`, {
      method: 'POST',
      headers,
      credentials: 'include',
      body: JSON.stringify({ test: 'data', csrf_token: csrfToken }),
    });
    
    if (!postResponse.ok) {
      console.error('POST请求失败:', postResponse.status, postResponse.statusText);
      const errorText = await postResponse.text();
      console.error('错误详情:', errorText);
      return false;
    }
    
    const postResult = await postResponse.json();
    console.log('POST测试结果:', postResult);
    
    return postResult.csrf_valid === true;
  } catch (error) {
    console.error('CSRF测试失败:', error);
    return false;
  }
}

export const baseRequestClient = new RequestClient({ baseURL: apiURL });

// 导出CSRF令牌函数
export { getCSRFTokenFromCookie, ensureCSRFToken, testCSRF };
